#include "Vertex.h"



Vertex::Vertex (float x, float y, float z) : _Pos (x, y, z) {}




const float* Vertex::normal () const
{
  return _Normal.data ();
}

const float* Vertex::position () const
{
  return _Pos.data ();
}

const float* Vertex::color () const
{
  return _color.data ();
}



void Vertex::set (float x, float y, float z)
{
  _Pos[0] = x; _Pos[1] = y; _Pos[2] = z;
}

void Vertex::set_color (float r, float g, float b)
{
  _color = Color3f (r, g, b);
}



void Vertex::change_normal (MyMatrix< Vertex >& vertexs)
{

  uint x = _Pos[0] + 0.5f; uint y = _Pos[1] + 0.5f;

  //     1
  //   4   2
  //     3
  float z1 = _Pos[2]; float z2 = _Pos[2];
  float z3 = _Pos[2]; float z4 = _Pos[2];
  _3D_Vector v1 (0, 0, 1);
  _3D_Vector v2 (0, 0, 1);
  _3D_Vector v3 (0, 0, 1);
  _3D_Vector v4 (0, 0, 1);

  if (y + 1 < vertexs.row_num ())
  {
    z1 = vertexs[y + 1][x][2];
    v1 = _3D_Vector (_Pos.data (), vertexs[y + 1][x].position ());
  }
  if (x + 1 < vertexs.column_num ())
  {
    z2 = vertexs[y][x + 1][2];
    v2 = _3D_Vector (_Pos.data (), vertexs[y][x + 1].position ());
  }
  if (y > 0)
  {
    z3 = vertexs[y - 1][x][2];
    v3 = _3D_Vector (_Pos.data (), vertexs[y - 1][x].position ());
  }
  if (x > 0)
  {
    z4 = vertexs[y][x - 1][2];
    v4 = _3D_Vector (_Pos.data (), vertexs[y][x - 1].position ());
  }
  _Normal_Before_Smooth = v2.cross (v1).unitary ()
          + v3.cross (v2).unitary ()
          + v4.cross (v3).unitary ()
          + v1.cross (v4).unitary ();
  _Normal = _Normal_Before_Smooth;

}


void Vertex::smooth_normal (MyMatrix< Vertex >& vertexs)
{

  uint x = _Pos[0] + 0.5f; uint y = _Pos[1] + 0.5f;

  const float FALLOUT_RATIO = 0.5f;

  if (y + 1 < vertexs.row_num ())
  {
    _Normal += vertexs[y + 1][x]._Normal_Before_Smooth * FALLOUT_RATIO;
  }
  if (x + 1 < vertexs.column_num ())
  {
    _Normal += vertexs[y][x + 1]._Normal_Before_Smooth * FALLOUT_RATIO;
  }
  if (y > 0)
  {
    _Normal += vertexs[y - 1][x]._Normal_Before_Smooth * FALLOUT_RATIO;
  }
  if (x > 0)
  {
    _Normal += vertexs[y][x - 1]._Normal_Before_Smooth * FALLOUT_RATIO;
  }
}